package com.lagou.filter;

import com.lagou.TimeBean;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.rpc.*;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

//指定是对消费方还是提供方进行拦截
@Activate(group = {CommonConstants.CONSUMER})
public class MonitorFilter implements Filter {

    private static final double TP90 = 0.9;
    private static final double TP99 = 0.99;

    List<TimeBean> list = new CopyOnWriteArrayList<>();

    public MonitorFilter() {
        Executors.newSingleThreadScheduledExecutor()
                .scheduleWithFixedDelay(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("定时任务启动，list的数量为：" + list.size());
                        if (list.size() > 0) {
                            Map<String, List<TimeBean>> map = list.stream().collect(Collectors.groupingBy(TimeBean::getMethodName));
                            for (Map.Entry<String, List<TimeBean>> entry : map.entrySet()) {
                                String methodName = entry.getKey();
                                List<TimeBean> timeBeans = entry.getValue();
                                if (CollectionUtils.isNotEmpty(timeBeans)) {
                                    long now = System.currentTimeMillis();
                                    timeBeans = timeBeans.stream()
                                            .filter(timeBean -> (now - timeBean.getCurrentTimeMillis()) < 1000 * 60)//最近一分钟的数据
                                            .sorted(Comparator.comparing(TimeBean::getTime))//根据时间正序排
                                            .collect(Collectors.toList());
                                    System.out.println(methodName + "最近一分钟数据的数量为" + timeBeans.size());
                                    System.out.println(methodName + "的TP90为：" + timeBeans.get((int) (timeBeans.size() * TP90)).getTime() + "毫秒");
                                    System.out.println(methodName + "的TP99为：" + timeBeans.get((int) (timeBeans.size() * TP99)).getTime() + "毫秒");
                                }
                            }
                        }
                    }
                }, 1, 5, TimeUnit.SECONDS);
    }

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long start = System.currentTimeMillis();
        try {
            return invoker.invoke(invocation);
        } finally {
            long end = System.currentTimeMillis();
            long time = end - start;
            //System.out.println("耗时：" + time + "毫秒");
            TimeBean timeBean = new TimeBean();
            timeBean.setTime(time);
            timeBean.setMethodName(invocation.getMethodName());
            timeBean.setCurrentTimeMillis(end);
            list.add(timeBean);
        }
    }

}
